﻿Imports System.Math
Public Class Vogel

    Private diferenciasProduccion(6) As Integer
    Private diferenciasBodegas(6) As Integer
    Private copiaDeLosCostosProduccion(6) As Integer
    Private copiaDeLosCostosBodega(6) As Integer
    Private paraSacarDiferencias As Boolean = False
    Private contadorAsignaciones As Integer = 1
    Dim ultimaFila As Integer
    Dim ultimaColumna As Integer

    ''inicializamos los arreglos para obtener las diferencias
    Private Sub inicializarDiferencias()
        For i As Integer = 1 To grupbox1.empresas
            diferenciasProduccion(i) = 0

        Next
        For i As Integer = 1 To grupbox1.bodegas
            diferenciasBodegas(i) = 0
        Next
    End Sub
    Private Function tomarCostosProduccion(ByVal fila As Integer)

        'Arreglo dimensionado que obtendrá los costos de la fila indicada
        ReDim copiaDeLosCostosProduccion(grupbox1.bodegas)
        Dim i As Integer = 1
        For j As Integer = 1 To grupbox1.bodegas
            For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                'detectamos el panel
                If elemento.Name = "Panel" & fila & j Then
                    'tomamos solamente los paneles que estan habilitados'
                    If elemento.Enabled = True Then
                        'capturamos los costos en los paneles habilitados y lo copiamos al arreglo
                        copiaDeLosCostosProduccion(i) = elemento.Controls.Item(2).Text
                        i += 1
                    End If
                End If
            Next
        Next
        'redimensionamos el arreglo de las copias con el fin de que elimine los 0 que entregó el 1 redimensionamiento
        ReDim Preserve copiaDeLosCostosProduccion(i - 1)
        If paraSacarDiferencias = True Then
            'si es el caso de obtener las diferencias ordenamos el arreglo, para obtener las 2 minimas diferencias
            Array.Sort(copiaDeLosCostosProduccion)
        End If
        'retornamos el numero de costos que se tomaron
        Return i
    End Function
    Private Function tomarCostosBodegas(ByVal columna As Integer)
        'Arreglo dimensionado que obtendrá los costos de la columna indicada
        ReDim copiaDeLosCostosBodega(grupbox1.empresas)
        Dim j As Integer = 1
        For i As Integer = 1 To grupbox1.empresas
            For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                If elemento.Name = "Panel" & i & columna Then
                    'tomamos solamente los paneles que estan habilitados'
                    If elemento.Enabled = True Then
                        'copiamos los costos que se encuentren en esa columna y en que los paneles estén habilitados
                        copiaDeLosCostosBodega(j) = elemento.Controls.Item(2).Text
                        j += 1
                    End If
                End If
            Next
        Next
        'redimensionamos el arreglo de las copias con el fin de que elimine los 0 que entregó el 1 redimensionamiento
        ReDim Preserve copiaDeLosCostosBodega(j - 1)

        If paraSacarDiferencias = True Then
            'si es el caso de obtener las diferencias ordenamos el arreglo, para obtener las 2 minimas diferencias
            Array.Sort(copiaDeLosCostosBodega)
        End If
        Return j
    End Function
    Private Sub construirDiferencias()
        ''variable que sirve para determinar si las diferencias serán sacadas
        paraSacarDiferencias = True
        Dim i As Integer = 1
        'Recorremos hasta el número de empresas que existen
        While (i <= grupbox1.empresas)
            'esta variable sirve para determinar cuando solamente existen como minimo 2 costos, caso especial
            'tomamos los costos hacia al lado
            Dim ncostos As Integer = tomarCostosProduccion(i)
            'este sirve para determinar las filas que se eliminaron; en las cuales las diferencias no deben ser calculadas
            If i = ultimaFila Then
                'poner -1 para saber la diferencia que ya no se tiene que calcular
                diferenciasProduccion(i) = -1
            Else
                If ncostos <= 2 Then
                    diferenciasProduccion(i) = copiaDeLosCostosProduccion(copiaDeLosCostosProduccion.Length - 1)
                Else
                    'caso base en los cuales quedan mas de 2 costos y la diferencia puede ser obtenida restando el 2 item y el primero/
                    'recordar que el arreglo fue ordenado.
                    diferenciasProduccion(i) = Abs(copiaDeLosCostosProduccion(2) - copiaDeLosCostosProduccion(1))
                End If

            End If
            i += 1
        End While
        'Recorremos hasta el número de bodegas que existen
        i = 1
        While (i <= grupbox1.bodegas)
            Dim ncostos As Integer = tomarCostosBodegas(i)
            If i = ultimaColumna Then
                diferenciasBodegas(i) = -1
            Else
                If ncostos <= 2 Then
                    diferenciasBodegas(i) = copiaDeLosCostosBodega(copiaDeLosCostosBodega.Length - 1)
                Else
                    diferenciasBodegas(i) = Abs(copiaDeLosCostosBodega(2) - copiaDeLosCostosBodega(1))
                End If

            End If
            i += 1
        End While
    End Sub

    Public Sub jueguemosVogel()
        Dim produccion, espacio As Integer
        Dim banderaDifEspacio As Boolean = False
        'Efecto recursivo

        'caso base de salida en que las asignaciones superan la operación elemental
        If contadorAsignaciones > grupbox1.empresas + grupbox1.bodegas - 1 Then
            PanelAMatriz()

        Else
            'inicializamos las diferencias con el tamaño de las bodegas y empresa
            inicializarDiferencias()
            'le damos la orden de que se sacaran las diferencias
            paraSacarDiferencias = True
            'vamos  a construir las diferencias. ¡Método encontrado arriba!
            construirDiferencias()
            'caso especial en el que las diferencias de producción es igual a la de las bodegas pero 0

            ''La primera parte solamente dice donde se va a realizar la asignación
            If diferenciasProduccion.Max = 0 And diferenciasBodegas.Max = 0 Then
                'recorremos la matriz con el fin de buscar donde se debe asignar
                For i = 1 To grupbox1.empresas
                    For j = 1 To grupbox1.bodegas
                        For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                            If elemento.Name = "Panel" & i & j Then
                                If elemento.Enabled = True Then
                                    For Each label As Control In grupbox1.splitContainer1.Panel1.Controls
                                        If label.Name = "UpDown" & i & 1 Then
                                            produccion = label.Text
                                        End If
                                        If label.Name = "UpDow" & 1 & j Then
                                            espacio = label.Text
                                        End If
                                    Next
                                    elemento.Controls.Item(1).Text = espacio
                                    elemento.Enabled = False
                                    'cambiamos la bandera, esta bandera determina que no realizará ninguna acción ya que trató el problema
                                    banderaDifEspacio = True
                                End If
                            End If
                        Next
                    Next
                Next
                'es una asignación así que se aumenta el contador
                contadorAsignaciones += 1
            ElseIf diferenciasProduccion.Max >= diferenciasBodegas.Max Then
                'este es el caso en el que se debe asignar tomando en cuenta la fila
                If banderaDifEspacio = False Then
                    'tomamos la fila donde se encuentra la mayor diferencia 
                    ultimaFila = Array.IndexOf(diferenciasProduccion, diferenciasProduccion.Max)
                    'como debemos mantener las posiciones de los costos en esa fila, el paraSacarDiferencias es falso
                    ' o sea no ordena el arreglo de diferencias.
                    paraSacarDiferencias = False
                    tomarCostosProduccion(ultimaFila)
                    'busco el menor costo en el arreglo de los costos que se obtuvieron
                    Dim valorMenor As Integer = 1000
                    For i = 1 To copiaDeLosCostosProduccion.Length - 1
                        If copiaDeLosCostosProduccion(i) < valorMenor Then
                            valorMenor = copiaDeLosCostosProduccion(i)
                        End If
                    Next
                    'con esto obtenemos la posición donde se encuentra el menor
                    For i = 1 To grupbox1.bodegas
                        For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                            If elemento.Name = "Panel" & ultimaFila & i Then
                                If elemento.Enabled = True Then
                                    If elemento.Controls.Item(2).Text = valorMenor Then
                                        ultimaColumna = i
                                        Exit For
                                        Exit For
                                    End If
                                End If
                            End If
                        Next
                    Next
                End If
            Else
                'si se debe asignar en las secciones de las bodegas, buscamos la posición de la mayor diferencia
                ultimaColumna = Array.IndexOf(diferenciasBodegas, diferenciasBodegas.Max)
                paraSacarDiferencias = False
                'tomamos los costos de las bodegas, o sea, por cada columna, recorremos las filas y obtenemos los costos
                tomarCostosBodegas(ultimaColumna)
                'buscamos el menor costo encontrado
                Dim valorMenor As Integer = 1000
                For i = 1 To copiaDeLosCostosBodega.Length - 1
                    If copiaDeLosCostosBodega(i) < valorMenor Then
                        valorMenor = copiaDeLosCostosBodega(i)
                    End If
                Next
                'buscamos la posición en la que se encuentra el menor costo
                For i = 1 To grupbox1.empresas
                    For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                        If elemento.Name = "Panel" & i & ultimaColumna Then
                            If elemento.Enabled = True Then
                                If elemento.Controls.Item(2).Text = valorMenor Then
                                    ultimaFila = i
                                    Exit For
                                    Exit For
                                End If
                            End If
                            'capturar de los label la producción y el espacio en bodega
                        End If
                    Next
                Next

            End If
            If banderaDifEspacio = False Then
                'comienza la asignación
                For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                    If elemento.Name = "Panel" & ultimaFila & ultimaColumna Then
                        For Each label As Control In grupbox1.splitContainer1.Panel1.Controls
                            If label.Name = "UpDown" & ultimaFila & 1 Then
                                produccion = label.Text
                            End If
                            If label.Name = "UpDow" & 1 & ultimaColumna Then
                                espacio = label.Text
                            End If
                        Next
                        ' hacer que vaya matando las filas o las columas cuando se vaya a realizar la asignacion 0
                        '' MsgBox("produccion" & produccion & "bodega" & espacio)
                        If produccion < espacio Then
                            elemento.Controls.Item(1).Text = produccion
                            For Each label As Control In grupbox1.splitContainer1.Panel1.Controls
                                If label.Name = "UpDown" & ultimaFila & 1 Then
                                    label.Text = 0
                                ElseIf label.Name = "UpDow" & 1 & ultimaColumna Then
                                    label.Text = label.Text - produccion
                                End If
                            Next
                            elemento.Enabled = False
                            For i As Integer = 1 To grupbox1.bodegas
                                For Each elementosBloquear As Control In grupbox1.splitContainer1.Panel1.Controls
                                    If elementosBloquear.Name = "Panel" & ultimaFila & i Then
                                        elementosBloquear.Enabled = False
                                    End If
                                Next
                            Next
                            contadorAsignaciones += 1
                        ElseIf produccion > espacio Then
                            elemento.Controls.Item(1).Text = espacio
                            elemento.Enabled = False
                            For Each label As Control In grupbox1.splitContainer1.Panel1.Controls
                                If label.Name = "UpDown" & ultimaFila & 1 Then
                                    label.Text = label.Text - espacio
                                ElseIf label.Name = "UpDow" & 1 & ultimaColumna Then
                                    label.Text = 0
                                End If
                            Next
                            For i As Integer = 1 To grupbox1.empresas
                                For Each elementosBloquear As Control In grupbox1.splitContainer1.Panel1.Controls
                                    If elementosBloquear.Name = "Panel" & i & ultimaColumna Then
                                        elementosBloquear.Enabled = False
                                    End If
                                Next
                            Next
                            contadorAsignaciones += 1
                        ElseIf produccion = espacio Then
                            'ver el tema de los 0
                            elemento.Controls.Item(1).Text = espacio
                            elemento.Enabled = False
                            contadorAsignaciones += 1
                            For Each label As Control In grupbox1.splitContainer1.Panel1.Controls
                                If label.Name = "UpDown" & ultimaFila & 1 Then
                                    label.Text = 0
                                ElseIf label.Name = "UpDow" & 1 & ultimaColumna Then
                                    label.Text = 0
                                End If
                            Next
                            'eliminar las columnas
                            For i As Integer = 1 To grupbox1.bodegas
                                For Each elementosBloquear As Control In grupbox1.splitContainer1.Panel1.Controls
                                    If elementosBloquear.Name = "Panel" & ultimaFila & i Then
                                        elementosBloquear.Enabled = False
                                    End If
                                Next
                            Next
                            paraSacarDiferencias = False
                            tomarCostosBodegas(ultimaColumna)
                            Dim valorMenor As Integer = 1000
                            For i = 1 To copiaDeLosCostosBodega.Length - 1
                                If copiaDeLosCostosBodega(i) < valorMenor Then
                                    valorMenor = copiaDeLosCostosBodega(i)
                                End If
                            Next
                            '' MsgBox("menorCosto" & valorMenor)
                            Dim ultimaFilaParcial As Integer
                            For i = 1 To grupbox1.empresas
                                For Each elemento0 As Control In grupbox1.splitContainer1.Panel1.Controls
                                    If elemento0.Name = "Panel" & i & ultimaColumna Then
                                        If elemento0.Enabled = True Then
                                            If elemento0.Controls.Item(2).Text = valorMenor Then
                                                ultimaFilaParcial = i

                                                Exit For
                                                Exit For
                                            End If
                                        End If
                                        'capturar de los label la producción y el espacio en bodega
                                    End If
                                Next
                            Next
                            '' MsgBox("la Fila" & ultimaFilaParcial)
                            For i As Integer = 1 To grupbox1.empresas
                                For Each elementosBloquear As Control In grupbox1.splitContainer1.Panel1.Controls
                                    If elementosBloquear.Name = "Panel" & i & ultimaColumna Then
                                        elementosBloquear.Enabled = False
                                    End If
                                Next
                            Next
                            For Each elementoPara0 As Control In grupbox1.splitContainer1.Panel1.Controls
                                If elementoPara0.Name = "Panel" & ultimaFilaParcial & ultimaColumna Then
                                    elementoPara0.Controls.Item(1).Text = 0
                                    contadorAsignaciones += 1
                                End If
                            Next


                        ElseIf contadorAsignaciones = grupbox1.empresas + grupbox1.bodegas - 1 Then

                            elemento.Controls.Item(1).Text = espacio
                            elemento.Enabled = False
                            contadorAsignaciones += 1


                        End If

                        ''bloquear los paneles donde se haga 0
                    End If

                Next
            End If
            jueguemosVogel()
            End If
        For i = 1 To grupbox1.empresas
            For j = 1 To grupbox1.bodegas
                For Each Control As Control In grupbox1.splitContainer1.Panel1.Controls
                    If Control.Name = "Panel" & i & j Then
                        Control.Enabled = True
                    End If
                Next
            Next
        Next




    End Sub


End Class
